from Subject import Subject
from Grid import Grid
from Player import Player
from Weapon import Weapon
#from time import sleep
import sys, pygame, math
from Unit import *
from MotionType import *
from pygame import QUIT
from pygame import KEYDOWN,K_ESCAPE,K_RETURN,K_BACKSPACE,K_m,K_p,K_LEFT,K_RIGHT,K_UP,K_DOWN, K_x, K_z, MOUSEMOTION, MOUSEBUTTONUP
from breadthFirstSearch import breadthFirstSearchStart, djikstraShortestPath, djikstraNew

class Model(Subject):

    def __init__(self,_mapFolder,mapfilename,_unitListFolder,_weaponListFolder,squareSize):
        super(Model, self).__init__()
        self._squareSize= int(squareSize)
        self._mapFolder=_mapFolder
        mapfile=_mapFolder+mapfilename
        self._selectedSquare=(0,0)
        self._grid=Grid(mapfile)
        prePlacedUnits=self._grid.getPrePlacedUnits()
        weaponFileName=_weaponListFolder+"\\weapons.txt"
        weaponFile=open(weaponFileName)
        weaponLine=weaponFile.readline()
        weaponStrength={}
        weaponAmmo={}
        weaponHits={}
        weaponClass={}
        weaponEvasion={}
        weaponHitChance={}
        weaponCritChance={}
        while(weaponLine!=''):
            weaponLine=weaponLine.replace('\n','')
            weaponLinePartition=weaponLine.split(',')
            print(weaponLinePartition)
            weaponName=weaponLinePartition[0]
            weaponStrengthSingle=float(weaponLinePartition[1])
            weaponAmmoSingle=int(weaponLinePartition[2])
            weaponHitsSingle=weaponLinePartition[3]
            weaponHitsSingle=weaponHitsSingle.split('+')
            weaponClassSingle=weaponLinePartition[4]
            weaponEvasionSingle=weaponLinePartition[5]
            weaponHitChanceSingle=weaponLinePartition[6]
            weaponCritChanceSingle=weaponLinePartition[7]
            weaponStrength[weaponName]=weaponStrengthSingle
            weaponAmmo[weaponName]=weaponAmmoSingle
            weaponHits[weaponName]=weaponHitsSingle
            weaponClass[weaponName]=weaponClassSingle
            weaponEvasion[weaponName]=weaponEvasionSingle
            weaponHitChance[weaponName]=weaponHitChanceSingle
            weaponCritChance[weaponName]=weaponCritChanceSingle
            weaponLine=weaponFile.readline()
        print(weaponAmmo)
        print(weaponHits)
        print(weaponStrength)
        self.weaponAmmo=weaponAmmo
        self.weaponHits=weaponHits
        self.weaponStrength=weaponStrength
        self.weaponClass=weaponClass
        self.weaponEvasion=weaponEvasion
        self.weaponHitChance=weaponHitChance
        self.weaponCritChance=weaponCritChance
        unitFileName=_unitListFolder+"\\unitlist.txt"
        unitFile=open(unitFileName)
        line=unitFile.readline()
        associations={}
        motionTypes={}
        baseMaxMovements={}
        canCaptures={}
        creationPlaces={}
        unitWeapons={}
        defenses={}
        strengths={}
        speeds={}
        lucks={}
        skills={}
        creationPlaces['base']={}
        creationPlaces['port']={}
        creationPlaces['airport']={}
        allUnits=[]
        #name,movement,Defense,Strength,Speed,Luck,Skill,MovementSpace:Cost+MovementSpace:Cost,characterReference,canCapture,creationSpot,inventoryItem+inventoryItem,costToMake
        while(line!=''):
            line=line.replace('\n','')
            linePartition=line.split(',')
            print(linePartition)
            name=linePartition[0]
            baseMaxMovement=linePartition[1]
            baseDefense=linePartition[2]
            baseStrength=linePartition[3]
            baseSpeed=linePartition[4]
            baseLuck=linePartition[5]
            baseSkill=linePartition[6]
            fullMovementStr=linePartition[7]
            movement={}
            allMovements=fullMovementStr.split('+')
            for movementStr in allMovements:
                currentMovement = movementStr.split(':')
                if(int(currentMovement[1])!=-1):
                    movement[currentMovement[0]]=int(currentMovement[1])
            charAssociation=linePartition[8]
            canCapture=linePartition[9]
            creationPlace=linePartition[10]
            fullWeaponList=linePartition[11]
            weaponList = fullWeaponList.split('+')
            creationCost=linePartition[12]
            allUnits.append(name)
            unitWeapons[name]=weaponList
            defenses[name]=int(baseDefense)
            strengths[name]=int(baseStrength)
            speeds[name]=int(baseSpeed)
            lucks[name]=int(baseLuck)
            skills[name]=int(baseSkill)
            motionTypes[name]=MotionType(name,movement)
            baseMaxMovements[name]=int(baseMaxMovement)
            associations[charAssociation]=name
            creationPlaces[creationPlace][name]=creationCost
            if(canCapture=='y'):
                canCaptures[name]=True
            else:
                canCaptures[name]=False
            line=unitFile.readline()
        print(associations)
        print(motionTypes)
        print(baseMaxMovements)
        print(canCaptures)
        print(creationPlaces)
        print(allUnits)
        self.associations=associations
        self.motionTypes=motionTypes
        self.baseMaxMovements=baseMaxMovements
        self.canCaptures=canCaptures
        self.creationPlaces=creationPlaces
        self.allUnits=allUnits
        self.defenses=defenses
        self.strengths=strengths
        self.skills=skills
        self.speeds=speeds
        self.lucks=lucks
        self.unitWeapons=unitWeapons
#        unitType='infantry'
#        infantryMotion=MotionType(unitType,{'HQ':1,'city':1,'base':1,'airport':1,'port':1,'shoal':1,'plain':1,'road':1,'mountain':2,'forest':2})
#        infantryMovement=4
        for unit in prePlacedUnits:
            unitSplit=unit.split(',')
            row=int(unitSplit[0])
            column=int(unitSplit[1])
            unitTypeChar=unitSplit[2]
            team=int(unitSplit[3])
            ai = ",".join(unitSplit[4:]).strip("() ")
            if(unitTypeChar in self.associations):
                unitType=self.associations[unitTypeChar]
                motion=self.motionTypes[unitType]
                baseMaxMovement=self.baseMaxMovements[unitType]
                canCaptureBuildings=self.canCaptures[unitType]
                unitDefense=self.defenses[unitType]
                unitStrength=self.strengths[unitType]
                unitSpeed=self.speeds[unitType]
                unitLuck=self.lucks[unitType]
                unitSkill=self.skills[unitType]
                unitWeapons=self.unitWeapons[unitType]
                unitInventory = []
                for weapon in unitWeapons:        
                    unitInventory.append(Weapon(weapon,self.weaponStrength[weapon],self.weaponAmmo[weapon],self.weaponHits[weapon],self.weaponClass[weapon],self.weaponEvasion[weapon],self.weaponHitChance[weapon],self.weaponCritChance[weapon]))
                unitToPlace = Unit(unitType,team,motion,unitDefense,unitStrength,unitSpeed,unitLuck,unitSkill,baseMaxMovement,ai,10,canCaptureBuildings,inventory = unitInventory)
                self._grid.getCell(row,column).setUnit(unitToPlace)
            else:
                print(''.join(['Unknown unit type: ',unitTypeChar]))
        self._players=[]
        self._teams=self._grid.teams
        for playerNum in range(self._teams):
            self._players.append(Player(str('player'+str(playerNum)),2000))
        self._selectedUnit=False
        self._selectedUnitSquareColumn=0
        self._selectedUnitSquareRow=0
        self._ableToFire=0
        self._ableToCapture=0
        self._won=False
        self._winningTeam=None
        self._newUnit=None
        self._targetedUnits=[]
        self._currentTarget=0
        self._movementSquares=()
        self._currentCreation=-1
        self.focus='grid'
        
    @property
    def mapFolder(self):
        return self._mapFolder
    
    @property
    def selectedUnit(self):
        return self._selectedUnit
        
    @property
    def selectedUnitSquareColumn(self):
        return self._selectedUnitSquareColumn
    
    @property
    def selectedUnitSquareRow(self):
        return self._selectedUnitSquareRow
        
    @property
    def grid(self):
        return self._grid

    @grid.setter
    def grid(self, value):
        self._grid = value
    
    @property
    def winner(self):
        return self._winningTeam
        
    def getDisplayText(self):
        if self.displayTextAge > 1:
            self.displayTextAge = 0
            self.displayText = None
        return self.displayText
        
    def moveUnit(self):
        self._selectedUnit=False
        y=self._selectedSquare[0]
        x=self._selectedSquare[1]
        if((self._grid.getCell(self._selectedUnitSquareRow,self._selectedUnitSquareColumn).getCaptureCost()!=None) and ((self._selectedUnitSquareRow,self._selectedUnitSquareColumn)!=self._selectedSquare)):
            self._grid.getCell(self._selectedUnitSquareRow,self._selectedUnitSquareColumn).setCaptureCost(20)
        moveUnit=self._grid.getCell(self._selectedUnitSquareRow,self._selectedUnitSquareColumn).getUnit()
        self._grid.getCell(self._selectedUnitSquareRow,self._selectedUnitSquareColumn).setUnit(None)
        self._grid.getCell(y,x).setUnit(moveUnit)
        self._grid.getCell(y,x).getUnit().setState('moved')
        for row in range(0,self._grid.getRows()):
            for column in range(0,self._grid.getColumns()):
                self._grid.getCell(row,column).setSecondary('regular')
        print(''.join(['Menu: Grid now focused']))
        self.focus='grid'
        self.focusedMenu=None
        self.startingHeight=0
        self.validMenuButtons=(0,0,0,0,0)
        self.currentMenuButton=0
        
    def moveTargetUnit(self, unitRow, unitCol, targetRow, targetCol):
        if((not self.validRowColumn(unitRow,unitCol)) or (not self.validRowColumn(targetRow,targetCol))):
            print("One of the grid positions is not valid")
        else:
            moveUnit=self._grid.getCell(unitRow,unitCol).getUnit()
            if(moveUnit == None):
                print('Error: Trying to move a unit that does not exist')
            else:
                #print('Trying to move unit')
                if(self._grid.getCell(unitRow,unitCol).getCaptureCost()!=None):
                    #print('Resetting capture for '+ str(unitRow) + ','+ str(unitCol))
                    self._grid.getCell(unitRow,unitCol).setCaptureCost(20)
                #print('Moving Unit')
                self._grid.getCell(unitRow,unitCol).setUnit(None)
                self._grid.getCell(targetRow,targetCol).setUnit(moveUnit)
                self._grid.getCell(targetRow,targetCol).getUnit().setState('moved')
                #print('Done')
                
    def validRowColumn(self,row,column):
        return((self._grid.validRow(row)) and (self._grid.validCol(column)))
    
    def calcDamage(self,weaponStr, defenseAmt, landType, attackingUnitStrength, attackCrit, attackHit, attackWepClass, enemyWepClass,enemySpe,friendlySki):
        attackingStr=0
        if(landType in ['forest','base','reef','city']):
            landTypeBonus = 1
        elif(landType in ['mountain','HQ']):
            landTypeBonus = 2
        elif(landType in ['castle']):
            landTypeBonus = 4
            attackingStr+=4
        else:
            landTypeBonus = 0 
        attackingStr+=weaponStr + attackingUnitStrength
        defendingStr=(defenseAmt+landTypeBonus)/2
        hitchance = int(attackHit) + int(friendlySki)
        hitchance -= int(enemySpe)/2
        x = random.randint(1,5)
        if(x > int(hitchance)):
            print('Missed!')
            return(0)
        damage=(attackingStr)-(defendingStr)
        if(attackWepClass == 'Sword' and enemyWepClass == 'Axe'):
            damage = damage+(damage/4)
        if(attackWepClass == 'Sword' and enemyWepClass == 'Lance'):
            damage = damage-(damage/4)
        if(attackWepClass == 'Lance' and enemyWepClass == 'Sword'):
            damage = damage+(damage/4)
        if(attackWepClass == 'Lance' and enemyWepClass == 'Axe'):
            damage = damage-(damage/4)
        if(attackWepClass == 'Axe' and enemyWepClass == 'Lance'):
            damage = damage+(damage/4)
        if(attackWepClass == 'Axe' and enemyWepClass == 'Sword'):
            damage = damage-(damage/4)
        x = random.randint(1,10)
        if(x <= int(attackCrit)):
            print('Crit! with '+str(attackCrit*2) +'% chance')
            damage = damage+(damage/2)
        return(max(damage,0))
        
    def attack(self,rowSource,colSource,rowTarget,colTarget,counterAttack):
#        friendlyHealth=self._grid.getCell(rowSource,colSource).getUnit().getHealth()
        friendlyStr=self._grid.getCell(rowSource,colSource).getUnit().getPrimaryWeapon().getStrength()
        friendlyUStr=self._grid.getCell(rowSource,colSource).getUnit().getStrength()
        friendlyCrit=self._grid.getCell(rowSource, colSource).getUnit().getPrimaryWeapon().getWeaponCritChance()
        friendlyHitPerc=self._grid.getCell(rowSource,colSource).getUnit().getPrimaryWeapon().getWeaponHitChance()
        friendlyWeapClass=self._grid.getCell(rowSource,colSource).getUnit().getPrimaryWeapon().getWeaponClass()
        friendlySkill=self._grid.getCell(rowSource,colSource).getUnit().getSkill()
        enemyWeapClass=self._grid.getCell(rowTarget,colTarget).getUnit().getPrimaryWeapon().getWeaponClass()
        enemyTeam=self._grid.getCell(rowTarget,colTarget).getUnit().getTeam()
        enemyHealth=self._grid.getCell(rowTarget,colTarget).getUnit().getHealth()
        enemyDefense=self._grid.getCell(rowTarget,colTarget).getUnit().getDefense()
        enemySpeed=self._grid.getCell(rowTarget,colTarget).getUnit().getSpeed()
        landType=self._grid.getCell(rowTarget, colTarget).getlType()
#        damage=(self._grid.getCell(rowSource,colSource).getUnit().getHealth()*0.75)
#        damage=self.calcDamage(friendlyStr,friendlyHealth,enemyDefense,enemyHealth)
        damage=self.calcDamage(friendlyStr, enemyDefense, landType, friendlyUStr, friendlyCrit, friendlyHitPerc, friendlyWeapClass,enemyWeapClass,enemySpeed,friendlySkill)
        print("Damage is "+str(damage))
        enemyHealth=enemyHealth-damage
        if(enemyHealth<=0):
            self._grid.getCell(rowTarget,colTarget).setUnit(None)
            if(self._grid.getCell(rowTarget,colTarget).getCaptureCost()!=None):
                self._grid.getCell(rowTarget,colTarget).setCaptureCost(20)
            if(self.defeated(enemyTeam)):
                if(enemyTeam==self._turnOrder[self._currentTurn]):
                    self.endTurn()
                self.removeTeam(enemyTeam)
        else:
            self._grid.getCell(rowTarget,colTarget).getUnit().setHealth(enemyHealth)
#            if(counterAttack):
#                self.attack(rowTarget,colTarget,rowSource,colSource,0)
                
    def removeTeam(self,team,newFaction=None):
        for i in range(self._grid.getRows()):
            for j in range(self._grid.getColumns()):
                if self._grid.getCell(i,j).getUnit() and self._grid.getCell(i,j).getUnit().getTeam()==team:
                    self._grid.getCell(i,j).setUnit(None)
                if(self._grid.getCell(i,j).getFaction()==team):
                    if(self._grid.getCell(i,j).getlType()=='HQ'):
                        self._grid.getCell(i,j).setlType('city')
                    self._grid.getCell(i,j).setFaction(newFaction)
        currentTeamBefore = self._turnOrder[self._currentTurn]
        self._turnOrder.remove(team)
        if(self._currentTurn == len(self._turnOrder)):
            self._currentTurn = self._currentTurn - 1
        elif(currentTeamBefore != self._turnOrder[self._currentTurn]):
            self._currentTurn = self._currentTurn - 1
        if(len(self._turnOrder)==1):
            self._won=True
            self._winningTeam=self._turnOrder[0]
            
    def getUnitList(self,teamNumber):
        unitPositions = []
        for i in range(self._grid.getRows()):
            for j in range(self._grid.getColumns()):
                if((self._grid.getCell(i,j).getUnit()!=None) and (self._grid.getCell(i,j).getUnit().getTeam()==teamNumber)):
                    unitPositions.append((i,j))
        return(unitPositions)
    
    def endTurn(self):
        for row in range(self._grid.getRows()):
            for col in range(self._grid.getColumns()):
                if((self._grid.getCell(row,col).getUnit()!=None) and (self._grid.getCell(row,col).getUnit().getTeam()==self._turnOrder[self._currentTurn])):
                    self._grid.getCell(row,col).getUnit().setState('unmoved')
        self._players[self._turnOrder[self._currentTurn]].setFocusedLocation(self._selectedSquare)
        self._currentTurn=self._currentTurn+1
        if(self._currentTurn>=len(self._turnOrder)):
            self._currentTurn=0
            self.turnCount += 1
        print(''.join(['Menu: Grid now focused']))
        self.focus='grid'
        self.focusedMenu=None
        self.currentTurn = 0
        self.startingHeight=0
        self._ableToFire=0
        self._targetedUnits=[]
        self._currentTarget=0
        self.validMenuButtons=(0,0,0,0,0)
        self.currentMenuButton=0
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    self.keyEscPress()
        victory = self.checkVictoryConditions()
        if victory:#check victory conditions here
            self.notify()
        else:
            self.startTurn()
    
    def checkVictoryConditions(self):
        for conditionGroup in self._grid.getVictoryConditions():
            for condition in conditionGroup[0]:
                conditionType = condition[1]
                conditionGoal = condition[2]
                conditionTeam = condition[0]
                conditionAction = condition[3]
                conditionMet = False
                if conditionType=="K" or conditionType=="C":
                    if not conditionGoal in self._turnOrder:
                        conditionMet = True
                if conditionType=="M":
                    for x in range(max(0,(conditionGoal[0]-conditionGoal[2])),min((conditionGoal[0]+conditionGoal[2]+1),self._grid.getColumns())):
                        for y in range(max(0,(conditionGoal[1]-conditionGoal[2])),min((conditionGoal[1]+conditionGoal[2]+1),self._grid.getRows())):
                            if self._grid.getCell(x,y).getUnit() and self._grid.getCell(x,y).getUnit().getTeam()==conditionTeam:
                                conditionMet = True
                if conditionType=="S" and self.turnCount==conditionGoal and conditionTeam in self._turnOrder:
                    conditionMet = True
                if conditionMet:
                    conditionGroup[0].remove(condition)
                    if not conditionAction == "W":
                        self.displayText=self._grid.getTextForEvent(conditionAction)
                        self.displayTextAge = 0
                    if conditionGroup[1] and len(conditionGroup[0])==0:
                        self._won = True
                        self._winningTeam = conditionTeam
                        return True           
        return False#no victory
    
    def startTurn(self):
        if self._currentTurn == 0:
            self.displayTextAge += 1
        if self.grid.getTextForTurn(str(self.turnCount)) and self._currentTurn == 0:
            self.displayText = self.grid.getTextForTurn(str(self.turnCount))
            self.displayTextAge = 0
        startingSquare=self._players[self._turnOrder[self._currentTurn]].getFocusedLocation()
        if(not(startingSquare==(-1,-1))):
            self._selectedSquare=startingSquare
        else:
            for row in range(self._grid.getRows()):
                for col in range(self._grid.getColumns()):
                    if((self._grid.getCell(row,col).getlType()=='HQ') and (self._grid.getCell(row,col).getFaction()==self._turnOrder[self._currentTurn])):
                        self._selectedSquare=(row,col)
        moneyPlaces=['city','base','HQ','port','airport']
        currentMoney=self._players[self._turnOrder[self._currentTurn]].getMoney()
        for row in range(self._grid.getRows()):
            for col in range(self._grid.getColumns()):
                if((self._grid.getCell(row,col).getUnit()!=None) and (self._grid.getCell(row,col).getUnit().getTeam()==self._turnOrder[self._currentTurn])):
                    if((self._grid.getCell(row,col).getFaction()!=None) and (self._grid.getCell(row,col).getFaction()==self._turnOrder[self._currentTurn]) and ((self._grid.getCell(row,col).getlType()=='city') or (self._grid.getCell(row,col).getlType()=='HQ') or (self._grid.getCell(row,col).getlType()=='base'))):
                        self._grid.getCell(row,col).getUnit().setHealth(min(self._grid.getCell(row,col).getUnit().getHealth()+2,10))
                if((self._grid.getCell(row,col).getlType() in moneyPlaces) and (self._grid.getCell(row,col).getFaction()==self._turnOrder[self._currentTurn])):
                    currentMoney=currentMoney+1000
        self._players[self._turnOrder[self._currentTurn]].setMoney(currentMoney)
        self.notify()
                    

    def defeated(self,team):
        unitsLeft=0
        HQ=0
        for i in range(self._grid.getRows()):
            for j in range(self._grid.getColumns()):
                unit=self._grid.getCell(i,j).getUnit()
                if((unit!=None) and (unit.getTeam()==team)):
#                    print(str(team)+': The unit at ('+str(i),',',str(j), ') is team '+str(unit.getTeam()))
                    unitsLeft=1
                if((self._grid.getCell(i,j).getlType()=='HQ') and (self._grid.getCell(i,j).getFaction()==team)):
                    HQ=1
        if(unitsLeft==0):# or (HQ==0):
            return(True)
        else:
            return(False)
        
    def keyUpPress(self):
        if(self.focus=='grid'):
            print(''.join(['Grid: Selected Square Up']))
            if(self._selectedSquare[0]>0):
                self._selectedSquare=(self._selectedSquare[0]-1,self._selectedSquare[1])
        elif(self.focus=='menu'):
            print(''.join(['Menu: Up']))
            if(self.focusedMenu==None):
                print(''.join(['Error: No FocusMenu with menu as focus']))
            elif(self.focusedMenu=='SingleMenu'):
                buttonValid=0
                while(buttonValid==0):
                    self.currentMenuButton=self.currentMenuButton-1
                    if(self.currentMenuButton<0):
                        self.currentMenuButton=len(self.validMenuButtons)-1
                    if(self.validMenuButtons[self.currentMenuButton]==1):
                        buttonValid=1
        elif(self.focus=='fire'):
            print(''.join(['Fire: Up']))
            self._currentTarget=self._currentTarget+1
            if(self._currentTarget==len(self._targetedUnits)):
                self._currentTarget=0
        elif(self.focus=='creation'):
            print('Creation: Up')
            self._currentCreation=self._currentCreation-1
            if(self._currentCreation<0):
                totalLength=len(self.creationPlaces[self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getlType()])
                self._currentCreation=totalLength-1
    def keyEscPress(self):
        self._won=True
        self._winningTeam=1
    def keyEnterPress(self):
        if(self.focus=='grid'):
            print(''.join(['Grid: Enter']))
            y,x=self._selectedSquare
            #If there isn't a unit selected
            if(not self.selectedUnit):
                #If there is a unit from the right team that has not moved, select it and highlight its movement squares
                if((self._grid.getCell(y,x).getUnit()!=None) and (self._grid.getCell(y,x).getUnit().getTeam()==self._turnOrder[self._currentTurn]) and (self._grid.getCell(y,x).getUnit().getState()!='moved')):
                    self._selectedUnit=True
                    self._selectedUnitSquareRow=y
                    self._selectedUnitSquareColumn=x
                    self._movementSquares=breadthFirstSearchStart(self._grid, self._grid.getCell(y,x).getUnit(), y, x)
                    for square in self._movementSquares:
                        self._grid.getCell(square[0],square[1]).setSecondary('highlight')
                elif((self._grid.getCell(y,x).getUnit()==None) and ((self._grid.getCell(y,x).getlType() in self.creationPlaces.keys()) and (self._grid.getCell(y,x).getFaction()==self._turnOrder[self._currentTurn]))):
                    print('Grid: Now Unit Creation')
                    self.focus='creation'
                    self._currentCreation=0
                else:
                    #Bring up a menu with just end available since it was an empty square
                    print(''.join(['Grid: Bringing Up Menu']))
                    self.focus='menu'
                    self.focusedMenu='SingleMenu'
                    self.startingHeight=0                                
                    self.validMenuButtons=(0,0,0,1,1) #wait,fire,cap,end,cancel
                    self.currentMenuButton=3
            #There is a unit selected
            else:
                #If there isn't a unit or is the selected unit
                if((self._grid.getCell(y,x).getUnit()==None) or ((y==self._selectedUnitSquareRow) and (x==self._selectedUnitSquareColumn))):
                    #Move if possible
                    if(self._grid.getCell(y,x).getSecondary()=='highlight'):
                        print(''.join(['Grid: Bringing Up Menu']))
                        self.focus='menu'
                        self.focusedMenu='SingleMenu'
                        self.startingHeight=0
                        #Check if able for cap
                        self._ableToCapture=0
                        landtype=self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getlType()
                        print(str(self._grid.getCell(self._selectedUnitSquareRow, self._selectedUnitSquareColumn).getUnit().getAbleToCapture()))
                        if((self._grid.getCell(self._selectedUnitSquareRow, self._selectedUnitSquareColumn).getUnit().getAbleToCapture()) and ((self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getFaction()!=self._turnOrder[self._currentTurn]) and ((landtype=='city') or (landtype=='airport') or (landtype=='port') or (landtype=='HQ') or (landtype=='base'))) and (self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getCaptureCost()!=None)):
                            self._ableToCapture=0
                        #Check if able to fire
                        self._ableToFire=0
                        minUnitAttackRange=1
                        maxUnitAttackRange=1
                        for rowChange in range((-1*maxUnitAttackRange),maxUnitAttackRange+1):
                            for colChange in range((-1*maxUnitAttackRange),maxUnitAttackRange+1):
                                squaresAway=abs(rowChange)+abs(colChange)
                                if((minUnitAttackRange<=squaresAway) and (squaresAway<=maxUnitAttackRange)):
                                    y=self._selectedSquare[0]+rowChange
                                    x=self._selectedSquare[1]+colChange
                                    if((self._grid.validRow(y)) and \
                                       (self._grid.validCol(x)) and \
                                       (self._grid.getCell(y,x).getUnit()!=None) and \
                                       (self._grid.getCell(y,x).getUnit().getTeam()!=self._turnOrder[self._currentTurn]) and \
                                       (((not(self._grid.getCell(self._selectedUnitSquareRow, self._selectedUnitSquareColumn).getUnit().getPrimaryWeapon()==None)) and \
                                       (self._grid.getCell(self._selectedUnitSquareRow, self._selectedUnitSquareColumn).getUnit().getPrimaryWeapon().getCurrentAmmo()>0) and \
                                       (self._grid.getCell(self._selectedUnitSquareRow, self._selectedUnitSquareColumn).getUnit().getPrimaryWeapon().hits(self._grid.getCell(y,x).getUnit().getType()))) or \
                                       (((not(self._grid.getCell(self._selectedUnitSquareRow, self._selectedUnitSquareColumn).getUnit().getSecondaryWeapon()==None)) and \
                                       (self._grid.getCell(self._selectedUnitSquareRow, self._selectedUnitSquareColumn).getUnit().getSecondaryWeapon().getCurrentAmmo()>0) and \
                                       (self._grid.getCell(self._selectedUnitSquareRow, self._selectedUnitSquareColumn).getUnit().getSecondaryWeapon().hits(self._grid.getCell(y,x).getUnit().getType())))))):
                                        self._ableToFire=1
                                        self._targetedUnits.append((y,x))
                                        self._currentTarget=0
                        self.validMenuButtons=(1,self._ableToFire,self._ableToCapture,0,1) #wait,fire,cap,end,cancel
                        self.currentMenuButton=0
                    else:
                        pass
        elif(self.focus=='menu'):
            print(''.join(['Menu: Enter']))
            if(self.focusedMenu==None):
                print(''.join(['Error: No FocusMenu with menu as focus']))
            elif(self.focusedMenu=='SingleMenu'):
                if(self.validMenuButtons[self.currentMenuButton]==1):
                    if(self.currentMenuButton==0):
                        print(''.join(['Menu: Moving Unit']))
                        self.moveUnit()
                    elif(self.currentMenuButton==1):
                        print(''.join(['Menu: Focusing Fire']))
                        self.focus='fire'
                    elif(self.currentMenuButton==2):
                        print('Menu: Capturing')
                        self.moveUnit()
                        #changeCap
#                        print('capping ('+str(self._selectedSquare[0])+','+str(self._selectedSquare[1])+')')
                        remainingCost=self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getCaptureCost()
                        remainingCost=remainingCost-math.ceil(self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getUnit().getHealth())
#                        print('Current Cost = '+str(self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getCaptureCost()))
                        if(remainingCost>0):
#                            print('Remaining Cost = '+str(remainingCost))
                            self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).setCaptureCost(remainingCost)
#                            print('After Cost = '+str(self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getCaptureCost()))
                        else:
                            if(self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getlType()=='HQ'):
                                self.removeTeam(self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getFaction(), self._turnOrder[self._currentTurn])
                            else:
#                                print('Remaining Cost = '+str(remainingCost))
                                self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).setCaptureCost(20)
                                self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).setFaction(self._turnOrder[self._currentTurn])
                    elif(self.currentMenuButton==3):
                        self.endTurn()
                    elif(self.currentMenuButton==4):
                        self.keyBkspPress()
                        self.keyBkspPress()#cancel twice to clear menu and selection
                        for event in pygame.event.get():
                            pass
        elif(self.focus=='fire'):
            print(''.join(['Fire: Enter']))
            (yTarget,xTarget)=self._targetedUnits[self._currentTarget]
            y=self._selectedSquare[0]
            x=self._selectedSquare[1]
            moveUnit=self._grid.getCell(self._selectedUnitSquareRow,self._selectedUnitSquareColumn).getUnit()
            self._grid.getCell(self._selectedUnitSquareRow,self._selectedUnitSquareColumn).setUnit(None)
            self._grid.getCell(y,x).setUnit(moveUnit)
            self._grid.getCell(y,x).getUnit().setState('moved')
            self.attack(y,x,yTarget,xTarget,True)
            #Remove Highlighted Tiles
            for row in range(0,self._grid.getRows()):
                for column in range(0,self._grid.getColumns()):
                    self._grid.getCell(row,column).setSecondary('regular')
            #Remove Menu
            self.focus='grid'
            self.focusedMenu=None
            self.startingHeight=0
            self.validMenuButtons=(0,0,0,0,0)
            self.currentMenuButton=0
            self._ableToFire=0 
            self._targetedUnits=[]
            #Remove Selected Unit
            self._selectedUnit=False
            self._selectedUnitSquareColumn=0
            self._selectedUnitSquareRow=0
        elif(self.focus=='creation'):
            print('Creation: Enter')
            currentRow=0
            for unitType,cost in  self.creationPlaces[self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getlType()].items():
                if(currentRow==self._currentCreation):
                    currentMoney=self._players[self._turnOrder[self._currentTurn]].getMoney()
                    if(int(cost)<=currentMoney):
                        self._players[self._turnOrder[self._currentTurn]].setMoney(currentMoney-int(cost))
                        motion=self.motionTypes[unitType]
                        baseMaxMovement=self.baseMaxMovements[unitType]
                        canCaptureBuildings=self.canCaptures[unitType]
                        unitDefense=self.defenses[unitType]
                        unitStrength=self.strengths[unitType]
                        unitSpeed=self.speeds[unitType]
                        unitLuck=self.lucks[unitType]
                        unitSkill=self.skills[unitType]
                        unitWeapons=self.unitWeapons[unitType]
                        unitInventory = []
                        for weapon in unitWeapons:        
                            unitInventory.append(Weapon(weapon,self.weaponStrength[weapon],self.weaponAmmo[weapon],self.weaponHits[weapon],self.weaponClass[weapon],self.weaponEvasion[weapon],self.weaponHitChance[weapon],self.weaponCritChance[weapon]))
                        #utype, team, motionType, defense, strength, speed, luck, skill, movement, health=10, ableToCapture=True, state='unmoved',attacking = None, inventory = None
                        unitToPlace = Unit(unitType,self._turnOrder[self._currentTurn],motion,unitDefense,unitStrength,unitSpeed,unitLuck,unitSkill,baseMaxMovement,10,canCaptureBuildings,inventory = unitInventory, state='moved')
                        #print(unitToPlace)
                        self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).setUnit(unitToPlace)
                        print('Creation: Grid now focused')
                        self._currentCreation=-1
                        self._newUnit=None
                        self.focus='grid'
                currentRow=currentRow+1
                        
    def keyBkspPress(self):
        if((self.focus=='grid') and (self._selectedUnit==True)):
            self._selectedUnit=False
            #No selected unit so remove all highlights
            for row in range(0,self._grid.getRows()):
                for column in range(0,self._grid.getColumns()):
                    self._grid.getCell(row,column).setSecondary('regular')
        elif(self.focus=='menu'):
            print(''.join(['Menu: Backspace']))
            print(''.join(['Menu: Grid now focused']))
            self.focus='grid'
            self.focusedMenu=None
            self.startingHeight=0
            self.validMenuButtons=(0,0,0,0,0)
            self.currentMenuButton=0
            self._ableToFire=0 
            self._targetedUnits=[]
        elif(self.focus=='fire'):
            print(''.join(['Fire: Backspace']))
            print(''.join(['Fire: Menu now focused']))
            self.focus='menu'
        elif(self.focus=='creation'):
            print('Creation: Backspace')
            print('Creation: Grid Now Focuesed')
            self.focus='grid'
            self._currentCreation=-1
            self._newUnit=None
            
    def keyMPress(self):
        print("Grid: Selected Square Coordinates ("+str(self._selectedSquare[0])+", "+str(self._selectedSquare[1])+")")
#        for row in range(self._grid.getRows()):
#            for col in range(self._grid.getColumns()):
#                self._grid.getCell(row,col).setSecondary('regular');
#                if((self._grid.getCell(row,col).getUnit()!=None) and (self._grid.getCell(row,col).getUnit().getTeam()==self._turnOrder[self._currentTurn])):
#                    self._grid.getCell(row,col).getUnit().setState('unmoved')
#        self._currentTurn=self._currentTurn+1
#        if(self._currentTurn==len(self._turnOrder)):
#            self._currentTurn=0
    def keyPPress(self):
        self._won=True
        self._winningTeam=0
    def keyLeftPress(self):
        if(self.focus=='grid'):
            print(''.join(['Grid: Selected Square Left']))
            if(self._selectedSquare[1]>0):
                self._selectedSquare=(self._selectedSquare[0],self._selectedSquare[1]-1)
        elif(self.focus=='menu'):
            print(''.join(['Menu: Left']))
            if(self.focusedMenu==None):
                print(''.join(['Error: No FocusMenu with menu as focus']))
            elif(self.focusedMenu=='SingleMenu'):
                pass
        elif(self.focus=='fire'):
            print(''.join(['Fire: Left']))
    def keyRightPress(self):
        if(self.focus=='grid'):
            print(''.join(['Grid: Selected Square Right']))
            if(self._selectedSquare[1]<(self._grid.getColumns()-1)):
                self._selectedSquare=(self._selectedSquare[0],self._selectedSquare[1]+1)
        elif(self.focus=='menu'):
            print(''.join(['Menu: Right']))
            if(self.focusedMenu==None):
                print(''.join(['Error: No FocusMenu with menu as focus']))
            elif(self.focusedMenu=='SingleMenu'):
                pass
        elif(self.focus=='fire'):
            print(''.join(['Fire: Left']))
            
    def keyDownPress(self):
        if(self.focus=='grid'):
            print(''.join(['Grid: Selected Square Down']))
            if(self._selectedSquare[0]<(self._grid.getRows()-1)):
                self._selectedSquare=(self._selectedSquare[0]+1,self._selectedSquare[1])
        elif(self.focus=='menu'):
            print(''.join(['Menu: Down']))
            if(self.focusedMenu==None):
                print(''.join(['Error: No FocusMenu with menu as focus']))
            elif(self.focusedMenu=='SingleMenu'):
                buttonValid=0
                while(buttonValid==0):
                    self.currentMenuButton=self.currentMenuButton+1
                    if(self.currentMenuButton==len(self.validMenuButtons)):
                        self.currentMenuButton=0
                    if(self.validMenuButtons[self.currentMenuButton]==1):
                        buttonValid=1
        elif(self.focus=='fire'):
            print(''.join(['Fire: Down']))
            self._currentTarget=self._currentTarget-1
            if(self._currentTarget==-1):
                self._currentTarget=len(self._targetedUnits)-1
        elif(self.focus=='creation'):
            print('Creation: Down')
            self._currentCreation=self._currentCreation+1
            totalLength=len(self.creationPlaces[self._grid.getCell(self._selectedSquare[0],self._selectedSquare[1]).getlType()])
            if(self._currentCreation>=totalLength):
                self._currentCreation=0
    
    def run(self):
        print("Running")
        self.focus='grid'
        self.displayText=None
        self.displayTextAge = 0
        self.turnCount = 0
        self._selectedUnit=False
        self._selectedUnitSquareColumn=0
        self._selectedUnitSquareRow=0
        self.movementSquares={}
        self.column=0
        self.row=0
        self.focusedMenu=None
        self._selectedSquare=(0,0)
        self._isComputer=self.grid.playerOrAI
        self._turnOrder=self.grid.turnOrder
        self._currentTurn=0
        self.validMenuButtons=None
        self.currentMenuButton=None
#        self._won=False
#        self._winningTeam=None
        self._won=False
        self._winningTeam=None
        self.running=True
        self.startTurn()
        self.notify()
        while(self._won==False):
            if not self._isComputer[self._turnOrder[self._currentTurn]]:
                for event in pygame.event.get():
                    if event.type == QUIT:
                        pygame.quit()
                        sys.exit()
                    elif event.type == MOUSEMOTION:
                        mousex, mousey = event.pos
                        x= int(mousex/self._squareSize)
                        y= int(mousey/self._squareSize)
                        if(self.focus == 'grid'):
                            x=self._observers[0]._currentTLCol + x
                            y=self._observers[0]._currentTLRow + y
                            if((y,x)!=self._selectedSquare):
                                if((0<=x<self._grid.getColumns()) and (0<=y<self._grid.getRows())):
                                    self._selectedSquare=(y, x)
                        elif(self.focus == 'menu'):
                            menuwidth = 68
                            menuheight = 20
                            menuItemCount=len(list(filter(None,self.validMenuButtons)))
                            menustartRow = self._selectedSquare[0] - self._observers[0]._currentTLRow
                            menustartCol = self._selectedSquare[1] - self._observers[0]._currentTLCol
                            menuLeft = menustartCol * self._squareSize
                            menuRight = menuLeft + menuwidth
                            menuTop = menustartRow * self._squareSize
                            #x= int(mousex/self._squareSize)
                            #y= int(mousey/self._squareSize)
                            x = mousex
                            y = mousey
                            if((menuLeft < x) and (x < menuRight)):
                                diffvert = y - menuTop
                                if(0 < diffvert):
                                    validMenuItemNumber = int(diffvert / menuheight)
                                    if(validMenuItemNumber < menuItemCount):
                                        currentValidNumber = -1
                                        for i in range(len(self.validMenuButtons)):
                                            if self.validMenuButtons[i] == 1:
                                                currentValidNumber = currentValidNumber + 1
                                                if(currentValidNumber == validMenuItemNumber):
                                                    menuItemNumber = i
                                        self.currentMenuButton = menuItemNumber
                        elif(self.focus == 'fire'):
                            for z in range(len(self._targetedUnits)):
                                    if((y,x) == self._targetedUnits[z]):
                                        self._currentTarget = z
                    elif event.type == MOUSEBUTTONUP:
                        mousex, mousey = event.pos
                        if event.button==1: #2 middle, 3 right, 4 scroll up, 5 scroll down
                            x=int(mousex/self._squareSize)
                            y=int(mousey/self._squareSize)
                            x=self._observers[0]._currentTLCol + x
                            y=self._observers[0]._currentTLRow + y
                            if(self.focus == 'fire'):
                                possibleTarget = False
                                for z in range(len(self._targetedUnits)):
                                    if((y,x) == self._targetedUnits[z]):
                                        possibleTarget = True
                                        self._currentTarget = z
                                if(possibleTarget):
                                    pygame.event.post(pygame.event.Event(KEYDOWN,{'key':K_RETURN}))
                                else:
                                    pygame.event.post(pygame.event.Event(KEYDOWN,{'key':K_BACKSPACE}))
                            else:
#                            if((y,x)!=self._selectedSquare):
#                                if((0<=x<self._grid.getColumns()) and (0<=y<self._grid.getRows())):
#                                    self._selectedSquare=(y,x)
                                pygame.event.post(pygame.event.Event(KEYDOWN,{'key':K_RETURN}))
                    elif event.type == KEYDOWN:
                        if event.key == K_ESCAPE:
                            self.keyEscPress()
                        if event.key == K_x:
                            self.keyEnterPress()
                        if event.key == K_RETURN:
                            self.keyEnterPress()
                        if event.key == K_BACKSPACE:
                            self.keyBkspPress()
                        if event.key == K_z:
                            self.keyBkspPress()
                        if event.key==K_m:
                            self.keyMPress()
                        if event.key==K_p:
                            self.keyPPress()
                        if event.key == K_LEFT:
                            self.keyLeftPress()
                        if event.key == K_RIGHT:
                            self.keyRightPress()
                        if event.key == K_UP:
                            self.keyUpPress()
                        if event.key == K_DOWN:
                            self.keyDownPress()
                    self.notify()
            else:
                print("I'm a computer!");
                unitPositionList = self.getUnitList(self._turnOrder[self._currentTurn])
                opponentHQs = []
                opponentUnits = []
                opponentUnitsWithAmt = []
                amountForOpponentUnits = 4
                creationPlaces = []
                ownedMenialBuildings = []
                selfHQ = []
                print("Preprocess")
                for row in range(self._grid.getRows()):
                    for col in range(self._grid.getColumns()):
                        #if((self._grid.getCell(row,col).getlType()=='HQ') and (not(self._grid.getCell(row,col).getFaction()==self._turnOrder[self._currentTurn]))):
                        if(self._grid.getCell(row,col).getlType()=='HQ'):
                            if(self._grid.getCell(row,col).getFaction()==self._turnOrder[self._currentTurn]):
                                selfHQ.append((row,col))
                            else:
                                opponentHQs.append((row,col))
                        if((self._grid.getCell(row,col).getUnit()!=None) and (self._grid.getCell(row,col).getUnit().getTeam()!=self._turnOrder[self._currentTurn])):
                            opponentUnits.append((row,col))
                            opponentUnitsWithAmt.append((row,col,amountForOpponentUnits))
                        if((self._grid.getCell(row,col).getlType()=='base') and (self._grid.getCell(row,col).getFaction()==self._turnOrder[self._currentTurn])):
                            creationPlaces.append((row,col))
                        if(self._grid.getCell(row,col).getFaction() == self._turnOrder[self._currentTurn]):
                            if((not((row,col) in selfHQ)) and (not((row,col) in creationPlaces))):
                                ownedMenialBuildings.append((row,col))
                for currentRowColumn in unitPositionList:
                    
                    currentUnit = self._grid.getCell(currentRowColumn[0], currentRowColumn[1]).getUnit()
                    print("Processing Unit")
                    self._selectedSquare = (currentRowColumn[0], currentRowColumn[1])
                    self.notify()
                    if(currentUnit.isAttacking()):
                        #shortestPathToHQ = djikstraShortestPath(self._grid,currentUnit,opponentHQs)
                        shortestPathToHQ = djikstraShortestPath(self._grid,currentUnit,opponentUnits)
                    else:
#                         defendingLocations = []
#                         for building in ownedMenialBuildings:
#                             amt = 5
#                             if(self._grid.getCell(building[0],building[1]).getUnit()==None):
#                                 amt = amt + 0
#                             elif(self._grid.getCell(building[0],building[1]).getUnit().getTeam()!=self._turnOrder[self._currentTurn]):
#                                 amt = amt + 5
#                             elif(currentRowColumn == building):
#                                 amt = amt + 3
#                             else:
#                                 amt = 0
#                             defendingLocations.append((building[0],building[1],amt))
#                         for building in selfHQ:
#                             amt = 3
#                             if(self._grid.getCell(building[0],building[1]).getUnit()==None):
#                                 amt = 7
#                             defendingLocations.append((building[0],building[1],amt))
#                         shortestPathToHQ = djikstraNew(self._grid,defendingLocations)
                        shortestPathToHQ=djikstraShortestPath(self._grid,currentUnit,[currentUnit.getdestination()])
                        #shortestPathToHQ = djikstraShortestPath(self._grid,currentUnit,selfHQ)
                    shortestPathToUnits = djikstraShortestPath(self._grid,currentUnit,opponentUnits)
                    unitsAreaToAttack = djikstraNew(self._grid, opponentUnitsWithAmt)
#                    print(str(shortestPathToHQ))
                    movementSquares=breadthFirstSearchStart(self._grid, currentUnit, currentRowColumn[0],currentRowColumn[1])
                    bestSpace = currentRowColumn
                    bestSpaceCost = float('-inf')
                    for currentTheorizedSpace in movementSquares:
                        #currentSpaceCost = random.randint(1,1000)
                        #print('Current space in question is ' + str(currentTheorizedSpace))
                        if(currentUnit.getaitype()=='M'):
                            destination=currentUnit.getdestination()
                            currentSpaceCost = -1 * (pow(currentTheorizedSpace[0]-destination[0],2) + pow(currentTheorizedSpace[1]-destination[1],2))
                        elif(currentUnit.getaitype()=='R'):
                            destination=currentRowColumn
                            currentSpaceCost = -1 * (pow(currentTheorizedSpace[0]-destination[0],2) + pow(currentTheorizedSpace[1]-destination[1],2))
                        else:
                            currentSpaceCost = 0
#                             if(currentUnit.getAbleToCapture()):
#                                 spaceCaptureCost = self._grid.getCell(currentTheorizedSpace[0],currentTheorizedSpace[1]).getCaptureCost()
#                                 if((not (spaceCaptureCost==None)) and (not (self._grid.getCell(currentTheorizedSpace[0],currentTheorizedSpace[1]).getFaction()==self._turnOrder[self._currentTurn]))):
#                                     currentSpaceCost = currentSpaceCost + 5
#                                     currentSpaceCost = currentSpaceCost + 20 - spaceCaptureCost
                            if(currentUnit.isAttacking()):
                                #currentSpaceCost = currentSpaceCost - (0.3 * shortestPathToUnits[currentTheorizedSpace[0]][currentTheorizedSpace[1]])
                                pass
                            else:
                                currentSpaceCost = currentSpaceCost + (1.05 * unitsAreaToAttack[currentTheorizedSpace[0]][currentTheorizedSpace[1]])
                            #if(currentTheorizedSpace in creationPlaces):
                            #    currentSpaceCost = currentSpaceCost - 10
                            #print('The Shortest Path To HQ is '+str(shortestPathToHQ[currentTheorizedSpace[0]][currentTheorizedSpace[1]]))
                            #print('Closest HQ is at '+str(closestHQ)+' at a distance of ' + str(closestHQDistance))
                            if(currentUnit.isAttacking()):
                                currentSpaceCost = currentSpaceCost - shortestPathToHQ[currentTheorizedSpace[0]][currentTheorizedSpace[1]]
                            else:
                                currentSpaceCost = currentSpaceCost - shortestPathToHQ[currentTheorizedSpace[0]][currentTheorizedSpace[1]]
                        if( bestSpaceCost < currentSpaceCost):
                            bestSpaceCost = currentSpaceCost
                            bestSpace = currentTheorizedSpace
                        #print('Cost for this square is '+str(currentSpaceCost))
                    if(currentRowColumn!=bestSpace):
                        print('Attempting to move unit from '+str(currentRowColumn)+' to '+str(bestSpace))
                        self.moveTargetUnit(currentRowColumn[0], currentRowColumn[1], bestSpace[0], bestSpace[1])
                    else:
                        print('Staying in the same place!')
                    self.notify()
                    #Time to do the action!
                    minUnitAttackRange=1
                    maxUnitAttackRange=1
                    targetedUnits = []
                    for rowChange in range((-1*maxUnitAttackRange),maxUnitAttackRange+1):
                        for colChange in range((-1*maxUnitAttackRange),maxUnitAttackRange+1):
                            squaresAway=abs(rowChange)+abs(colChange)
                            if((minUnitAttackRange<=squaresAway) and (squaresAway<=maxUnitAttackRange)):
                                y=bestSpace[0]+rowChange
                                x=bestSpace[1]+colChange
                                if((self._grid.validRow(y)) and \
                                   (self._grid.validCol(x)) and \
                                   (self._grid.getCell(y,x).getUnit()!=None) and \
                                   (self._grid.getCell(y,x).getUnit().getTeam()!=self._turnOrder[self._currentTurn]) and \
                                   (((not(self._grid.getCell(bestSpace[0], bestSpace[1]).getUnit().getPrimaryWeapon()==None)) and \
                                   (self._grid.getCell(bestSpace[0], bestSpace[1]).getUnit().getPrimaryWeapon().getCurrentAmmo()>0) and \
                                   (self._grid.getCell(bestSpace[0], bestSpace[1]).getUnit().getPrimaryWeapon().hits(self._grid.getCell(y,x).getUnit().getType()))) or \
                                   (((not(self._grid.getCell(bestSpace[0], bestSpace[1]).getUnit().getSecondaryWeapon()==None)) and \
                                   (self._grid.getCell(bestSpace[0], bestSpace[1]).getUnit().getSecondaryWeapon().getCurrentAmmo()>0) and \
                                   (self._grid.getCell(bestSpace[0], bestSpace[1]).getUnit().getSecondaryWeapon().hits(self._grid.getCell(y,x).getUnit().getType())))))):
                                    targetedUnits.append((y,x,self._grid.getCell(y,x).getUnit().getHealth()))
                    if(currentUnit.getaitype()!='M'):
                        if(len(targetedUnits)!=0):
                            print('Can fire!')
                            bestToAttack = 0
                            lowestHealth = targetedUnits[0][2]
                            for i in range(1,len(targetedUnits)):
                                if(targetedUnits[i][2]<lowestHealth):
                                    bestToAttack = i
                                    lowestHealth = targetedUnits[i][2] 
                            self.attack(bestSpace[0],bestSpace[1],targetedUnits[bestToAttack][0],targetedUnits[bestToAttack][1],True)
                        elif((currentUnit.getAbleToCapture()) and (self._grid.getCell(bestSpace[0],bestSpace[1]).getCaptureCost() != None) and (self._grid.getCell(bestSpace[0],bestSpace[1]).getFaction() != self._turnOrder[self._currentTurn])):
                            print('Trying to capture')
                            currentCaptureCost = self._grid.getCell(bestSpace[0],bestSpace[1]).getCaptureCost()
                            remainingCaptureCost = currentCaptureCost - math.ceil(self._grid.getCell(bestSpace[0],bestSpace[1]).getUnit().getHealth())
                            if(remainingCaptureCost > 0):
                                self._grid.getCell(bestSpace[0],bestSpace[1]).setCaptureCost(remainingCaptureCost)
                            else:
                                if(self._grid.getCell(bestSpace[0],bestSpace[1]).getlType()=='HQ'):
                                    self.removeTeam(self._grid.getCell(bestSpace[0],bestSpace[1]).getFaction(), self._turnOrder[self._currentTurn])
                                else:
                                    self._grid.getCell(bestSpace[0],bestSpace[1]).setCaptureCost(20)
                                    self._grid.getCell(bestSpace[0],bestSpace[1]).setFaction(self._turnOrder[self._currentTurn])
                            self.notify()
                    
                for creationPlace in creationPlaces:
                    if(self._grid.getCell(creationPlace[0],creationPlace[1]).getUnit() == None):
                        numberOfUnitsTotal = 0
                        numberOfUnitsAttacking = 0
                        for row in range(self._grid.getRows()):
                            for col in range(self._grid.getColumns()):
                                if((self._grid.getCell(row,col).getUnit()!=None) and (self._grid.getCell(row,col).getUnit().getTeam()==self._turnOrder[self._currentTurn])):
                                    numberOfUnitsTotal = numberOfUnitsTotal + 1
                                    if(self._grid.getCell(row,col).getUnit().isAttacking() == True):
                                        numberOfUnitsAttacking = numberOfUnitsAttacking + 1
                        if(numberOfUnitsTotal == 0):
                            attackingPercent = 100
                        else:
                            attackingPercent = numberOfUnitsAttacking / numberOfUnitsTotal
                        bestUnitToMake = None
                        unitCost = None
                        currentMoney=self._players[self._turnOrder[self._currentTurn]].getMoney()
                        for unitType,cost in  self.creationPlaces[self._grid.getCell(creationPlace[0],creationPlace[1]).getlType()].items():
                            if(unitType == 'infantry'):
                                if(int(cost) <= currentMoney):
                                    bestUnitToMake = 'infantry'
                                    unitCost = int(cost)
                        if(bestUnitToMake != None):
                            self._selectedSquare = (creationPlace[0], creationPlace[1])
                            self.notify()
                            self._players[self._turnOrder[self._currentTurn]].setMoney(currentMoney-int(unitCost))
                            motion=self.motionTypes[bestUnitToMake]
                            baseMaxMovement=self.baseMaxMovements[bestUnitToMake]
                            canCaptureBuildings=self.canCaptures[bestUnitToMake]
                            unitDefense=self.defenses[bestUnitToMake]
                            unitStrength=self.strengths[bestUnitToMake]
                            unitSpeed=self.speeds[bestUnitToMake]
                            unitLuck=self.lucks[bestUnitToMake]
                            unitSkill=self.skills[bestUnitToMake]
                            unitWeapons=self.unitWeapons[bestUnitToMake]
                            unitInventory = []
                            for weapon in unitWeapons:        
                                unitInventory.append(Weapon(weapon,self.weaponStrength[weapon],self.weaponAmmo[weapon],self.weaponHits[weapon],self.weaponClass[weapon],self.weaponEvasion[weapon],self.weaponHitChance[weapon],self.weaponCritChance[weapon]))
                            if(attackingPercent < self._players[self._turnOrder[self._currentTurn]].getPercentageAttacking()):
                                unitToAttack = True
                                print('Creating an attacking unit')
                            else:
                                unitToAttack = False
                                print('Creating an defending unit')
                            unitToMake = Unit(bestUnitToMake,self._turnOrder[self._currentTurn],motion,unitDefense,unitStrength,unitSpeed,unitLuck,unitSkill,baseMaxMovement,10,canCaptureBuildings,inventory = unitInventory,attacking = unitToAttack)
                            self._grid.getCell(creationPlace[0],creationPlace[1]).setUnit(unitToMake)
                            self.notify()
                self.endTurn()
        print("Finished")
